import React, { useEffect, useState } from 'react';
import { Modal, Image, Button, Form, Input, InputNumber, Select, Switch, Tree, message, Space, AutoComplete, Upload } from 'antd';
import {
  CaretLeftOutlined, DeleteOutlined, DoubleRightOutlined, EditOutlined, ExclamationCircleFilled, PlusOutlined, LoadingOutlined,
  SettingOutlined, BarcodeOutlined, NodeIndexOutlined, ToolOutlined, ContactsOutlined, PartitionOutlined, TeamOutlined, UserSwitchOutlined, TableOutlined
} from '@ant-design/icons';
import "./index.less";
import { addMenu, delMenu, editMenu, getTypeList, getMenuList, upload } from '@/services/demo/UserController';
import { ProCard } from '@ant-design/pro-components';
import { MenuCode } from "@/../../code";
import AuthButton from "@/components/AuthButton";
import AuthBtn from "./AuthBtn";
import type { GetProp, UploadProps } from 'antd';

type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];
interface ExpandTreeData {
  sort: number;
  id: string,
  name: string,
  children?: ExpandTreeData[];
}
const initialValues = { order: 0, status: 1, description: "" };
const MenuIconList = [
  { value: "CaretLeftOutlined", label: <CaretLeftOutlined /> },
  { value: "DoubleRightOutlined", label: <DoubleRightOutlined /> },
  { value: "SettingOutlined", label: <SettingOutlined /> },
  { value: "BarcodeOutlined", label: <BarcodeOutlined /> },
  { value: "NodeIndexOutlined", label: <NodeIndexOutlined /> },
  { value: "ToolOutlined", label: <ToolOutlined /> },
  { value: "ContactsOutlined", label: <ContactsOutlined /> },
  { value: "PartitionOutlined", label: <PartitionOutlined /> },
  { value: "TeamOutlined", label: <TeamOutlined /> },
  { value: "UserSwitchOutlined", label: <UserSwitchOutlined /> },
  { value: "TableOutlined", label: <TableOutlined /> }
];
let dataList: ExpandTreeData[] = [];
const generateList = (data: ExpandTreeData[]) => {
  for (let i = 0; i < data.length; i++) {
    const node = data[i];
    dataList.push({ ...node });
    if (node.children) {
      generateList(node.children);
    }
  }
};
const findNodeByPos = (pos: string, tree: any) => {
  const cooperate = pos.slice(2).split("-").map(Number);

  const obj = { code: "", name: "", trunk: false, root: false };
  obj.root = cooperate.length === 1;
  cooperate.forEach(coo => {
    obj.name += tree[coo].name + "->";
    obj.code += tree[coo].path + "_";
    tree = tree[coo].children;
  });

  obj.name = obj.name.slice(0, -2);
  obj.code = (obj.code || "").replace("_", "-");
  obj.trunk = !tree.length;
  return obj;
};

const getParentKey = (id: React.Key, tree: ExpandTreeData[]): React.Key => {
  let parentKey: React.Key;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some((item) => item.id === id)) {
        parentKey = node.id;
      } else if (getParentKey(id, node.children)) {
        parentKey = getParentKey(id, node.children);
      }
    }
  }
  return parentKey!;
};

const App: React.FC = () => {
  const [form] = Form.useForm();
  const [nodeInfo, setNodeInfo] = useState<{ root?: Boolean, name?: string, code?: string; trunk?: boolean; }>({});
  const [temFormData, setTemFormData] = useState<any>();
  const [formDisabled, setFormDisabled] = useState<boolean>(true);
  const [imgLoading, setImgLoading] = useState<boolean>(false);
  const [selectedKey, setSelectedKey] = useState<React.Key>();
  const [treeData, setTreeData] = useState<ExpandTreeData[]>([]);
  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  const [searchValue, setSearchValue] = useState('');
  const [autoExpandParent, setAutoExpandParent] = useState(true);
  const [mode, setMode] = useState("预览");
  const [menuLoading, setMenuLoading] = useState(true);
  const [appTypeOptions, setAppTypeOptions] = useState();

  useEffect(() => {
    getTypeList().then(res => {
      setAppTypeOptions(res.result);
    })
    refreshTree();
  }, []);


  const onHandlePlus = () => {
    setMode("新增");
    setTemFormData(form.getFieldsValue());
    const obj = { ...initialValues, parentId: form.getFieldValue("id") || 0 };

    form.resetFields();
    form.setFieldsValue(obj);
    setFormDisabled(false);
  };
  const onHandleEdit = () => {
    setMode("编辑");
    console.log(temFormData);
    if (temFormData) {
      form.setFieldsValue(temFormData);
    } else {
      setTemFormData(form.getFieldsValue());
    }
    setFormDisabled(false);
  };
  const onHandleDelete = () => {
    const id = form.getFieldValue("id");
    const name = form.getFieldValue("name");
    if (id) {
      Modal.confirm({
        mask: false,
        title: "删除",
        content: `确定是否删除【${name}】`,
        icon: <ExclamationCircleFilled />,
        onOk() {
          delMenu(id).then(res => {
            if (res.success) {
              message.success(`【${name}】已被删除`);
              if (selectedKey === id) {
                setSelectedKey(undefined)
                form.resetFields();
              }
              refreshTree();
            }
          });
        },
        onCancel() {
          message.warning('已取消');
        }
      });

    } else {
      message.warning('请先选中节点');
    }

  };
  const onselect = (selectedKeys: React.Key[], info: any) => {
    // 取消重复点击
    console.log(treeData);
    if ((info.node.key === selectedKey)) {

      setSelectedKey(undefined);
      form.resetFields();
      return
    }
    setSelectedKey(selectedKeys[0]);
    console.log(selectedKeys, info);
    const findItem = dataList.find(item => item.id == info.node.id);
    setNodeInfo(findNodeByPos(info.node.pos!, treeData));
    findItem && form.setFieldsValue(findItem);
  };
  const onExpand = (newExpandedKeys: React.Key[]) => {
    setExpandedKeys(newExpandedKeys);
    setAutoExpandParent(false);
  };

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    console.log(value, dataList, treeData);

    const newExpandedKeys = dataList
      .map((item) => {
        if (item.name.indexOf(value) > -1) {
          console.log(getParentKey(item.id, treeData));

          return getParentKey(item.id, treeData);
        }
        return null;
      })
      .filter((item, i, self): item is React.Key => !!(item && self.indexOf(item) === i));

    setExpandedKeys(newExpandedKeys);
    setSearchValue(value);
    setAutoExpandParent(true);
  };

  const beforeUpload = (file: FileType) => {
    const isImg = file.type.includes("image");
    if (!isImg) {
      message.error('只能上传图片');
      return false;
    }
    const isLt2M = file.size / 1024 / 1024 < 0.5;
    if (!isLt2M) {
      message.error('图片大小不能大于500KB!');
      return false;
    }
    const formData = new FormData() as any;
    formData.append("file", file);
    setImgLoading(true);
    upload(formData).then(res => {
      form.setFieldValue("icon", res.result)
      setImgLoading(false);
    })
    return true;
  };

  const loop = (data: ExpandTreeData[]): any[] =>
    data.map((item) => {
      const strTitle = item.name as string;
      const index = strTitle.indexOf(searchValue);
      const beforeStr = strTitle.substring(0, index);
      const afterStr = strTitle.slice(index + searchValue.length);
      const name =
        index > -1 ? (
          <span>
            {beforeStr}
            <span className="site-tree-search-value">{searchValue}</span>
            {afterStr}
          </span>
        ) : (
          <span>{strTitle}</span>
        );
      if (item.children) {
        return { name, id: item.id, children: loop(item.children) };
      }

      return {
        name,
        id: item.id,
      };
    });
  const onFinish = async (values: any) => {

    console.log(values, nodeInfo, treeData);
    let data: any;
    if (mode === "新增") {
      data = await addMenu(values);
    } else {
      data = await editMenu(values);
    }
    if (data.success) {
      message.success("菜单" + mode + "成功");
      setMode("预览");
      setFormDisabled(true)
      refreshTree();
    }
  };
  const refreshTree = () => {
    getMenuList().then(res => {
      setTreeData(res.result);
      dataList = [];
      generateList(res.result);
      console.log(dataList);
      setMenuLoading(false);
    });
  }
  const onFinishFailed = (errorInfo: any) => {
    console.log('Failed:', errorInfo);
  };

  const onTypeChange = (value: string) => {
    console.log(value);
    if (value == "10") {
      form.setFieldValue("path", "");
    } else {
      form.setFieldValue("href", "");
    }
    form.setFieldValue("code", "");
  };
  const onSortChange = (value: number | null) => {
    console.log(value);

  };
  const onStatusChange = (value: boolean) => {
    form.setFieldValue("status", Number(value));
  };

  const onHandleFormCancel = () => {
    setFormDisabled(true);
    setMode("预览");
    form.setFieldsValue(temFormData);
  };

  const onPathLinkChange = (e: React.ChangeEvent<HTMLInputElement>, type: number) => {
    console.log(type, e.target.value, nodeInfo.code);
    if (nodeInfo.code) {

      if (type == 1) {
        // form.setFieldValue("code", e.target.value);
      } else {
        const findStr = nodeInfo.code!.split(/[-_]/).slice(0, -1).pop();

        const suffix = mode === "新增" ? nodeInfo.code : nodeInfo.code!.slice(0, nodeInfo.code!.indexOf(findStr!));
        form.setFieldValue("code", suffix + e.target.value);
      }
    } else {
      form.setFieldValue("code", e.target.value)
    }
    form.validateFields(["code"]);
  };
  return (
    <div id='auth_id'>
      <ProCard split="vertical" style={{ height: "calc(100vh - 176px)" }}>
        <ProCard style={{ height: "100%", overflowY: "auto" }} headerBordered loading={menuLoading} colSpan="20%">
          <Input.Search style={{ marginBottom: "15px" }} placeholder="输入关键词进行过滤" onChange={onChange} />
          <Tree
            onSelect={onselect}
            onExpand={onExpand}
            expandedKeys={expandedKeys}
            autoExpandParent={autoExpandParent}
            treeData={loop(treeData)}
            fieldNames={{ title: "name", key: "id", children: "children" }}
          />
        </ProCard>
        {/* title={(nodeInfo.name || "菜单信息") + " - " + title} */}
        <ProCard colSpan="80%" style={{ height: "100%", overflowY: "auto" }} headerBordered>
          <Space style={{ marginBottom: "20px" }}>
            <AuthButton type='primary' permission={MenuCode['BTN_ADD']} onClick={onHandlePlus} value="plus" icon={<PlusOutlined />} >新增</AuthButton>
            {Boolean(selectedKey) && <AuthButton permission={MenuCode['BTN_EDIT']} onClick={onHandleEdit} value="edit" type="primary" icon={<EditOutlined />}>编辑</AuthButton>}
            {Boolean(selectedKey) && <AuthButton permission={MenuCode['BTN_DEL']} onClick={onHandleDelete} value="delete" icon={<DeleteOutlined />}>删除</AuthButton>}
            {nodeInfo.trunk && <AuthBtn nodeInfo={nodeInfo} menuId={form.getFieldValue("id") || temFormData?.id} />}
          </Space>
          <Form
            form={form}
            disabled={formDisabled}
            labelCol={{ span: 2 }}
            onFinish={onFinish}
            onFinishFailed={onFinishFailed}
            initialValues={initialValues}
          >
            <Form.Item name="id" hidden>
              <Input placeholder='序号' disabled />
            </Form.Item>

            <Form.Item
              label="父节点"
              name="parentId"
            >
              <Input placeholder='请输入父节点' disabled />
            </Form.Item>
            <Form.Item noStyle dependencies={["parentId"]}>
              {({ getFieldValue }) => !getFieldValue("parentId") ? <Form.Item
                label="应用类型"
                name="appType"
                rules={[{ required: true, message: "请选择应用类型" }]}
              >
                <Select
                  placeholder="请选择应用类型"

                  allowClear
                  fieldNames={{ label: "appTypeName", value: "appType" }}
                  options={appTypeOptions}
                >
                </Select>
              </Form.Item> : null}
            </Form.Item>
            <Form.Item
              label="类型"
              name="type"
              rules={[{ required: true, message: "请选择类型" }]}
            >
              <Select
                placeholder="Select a option and change input text above"
                onChange={onTypeChange}
                allowClear
                options={[{ value: '10', label: "路径" }, { value: '20', label: "链接" }]}
              >
              </Select>
            </Form.Item>

            <Form.Item
              label="名称"
              name="name"
              rules={[{ required: true, message: 'Please input name' }]}
            >
              <Input placeholder='Please input name' />
            </Form.Item>
            <Form.Item noStyle dependencies={["parentId"]}>
              {({ getFieldValue }) => !getFieldValue("parentId") ? <Form.Item label="图标" name="icon" valuePropName="icon">
                <Upload style={{ width: "100px", height: "100px" }} beforeUpload={beforeUpload} action="#" listType="picture-card" showUploadList={false} >
                  {form?.getFieldValue("icon") ? <Image preview={false} object-fit="cover" max-width="100%" src={form?.getFieldValue("icon")} /> :
                    <button style={{ border: "none", background: "none" }}>
                      {imgLoading ? <LoadingOutlined /> : <PlusOutlined />}
                      <div>Upload</div>
                    </button>}
                </Upload>
              </Form.Item> : <Form.Item label="图标" name="icon">
                <AutoComplete placeholder="请输入图标" allowClear options={MenuIconList} />
              </Form.Item>}
            </Form.Item>


            <Form.Item noStyle dependencies={["type"]}>
              {({ getFieldValue }) => getFieldValue('type') === '20' ? <Form.Item
                label="链接"
                name="href"
                rules={[{ required: true, message: 'Please input href' }, { type: 'url', warningOnly: true }, { type: 'string', min: 6 }]}
              >
                <Input placeholder='Please input link' onChange={(e) => onPathLinkChange(e, 1)} />
              </Form.Item> : <Form.Item
                label="路径"
                name="path"
                rules={[{ required: true, message: 'Please input path' }]}
              >
                <Input placeholder='Please input path' onChange={(e) => onPathLinkChange(e, 2)} />
              </Form.Item>}
            </Form.Item>
            {/* 编码这里提交根据路径生成 */}
            <Form.Item
              label="编码"
              rules={[{ required: true, message: 'Please input encode' }]}
              name="code"
            // hidden
            >
              <Input />
            </Form.Item>

            <Form.Item
              label="排序"
              name="order"
            >
              <InputNumber min={0} precision={0} onChange={onSortChange} changeOnWheel />
            </Form.Item>
            <Form.Item
              label="描述"
              name="description"
            >
              <Input.TextArea autoSize={{ minRows: 2 }} placeholder='Please input description' />
            </Form.Item>
            <Form.Item
              label="状态"
              name="status"
              hidden
            >
              <Switch onChange={onStatusChange} />
            </Form.Item>
            {mode !== "预览" && <Form.Item>
              <Space>
                <Button type="primary" htmlType="submit">
                  {mode == "新增" ? "保存" : "更新"}
                </Button>
                <Button onClick={onHandleFormCancel}>取消</Button>
              </Space>
            </Form.Item>}
          </Form>
        </ProCard>
      </ProCard>
    </div >
  );
};

export default App;